package exquery

import setupx.entity.ClassOrgan
import exquery.util.CommonUtil
import org.apache.log4j.Logger
import exquery.valuebeans.export.OrganVO
import exquery.common.OrganUtil
import exquery.util.WildCardUtil
import setupx.entity.ClassSample

class OrgansService {

    static transactional = true
    Logger gLogger = Logger.getLogger(OrgansService.class)

    /**
     * to get distinct list of organs for list of class Ids
     * @param classIds
     * @return
     */
    def getOrgansByClassIds(def classIds) {

      def organsList

      if(classIds!=null){
          if(classIds instanceof Collection){
              if( classIds.size() !=0 ){
                organsList = ClassOrgan.executeQuery("Select distinct co.organ_name from setupx.entity.ClassOrgan co where co.experimentclass.id in (:classIds) ",["classIds":classIds])
              }
          }else if(classIds instanceof Long ){
            organsList = ClassOrgan.executeQuery("Select distinct co.organ_name from setupx.entity.ClassOrgan co where co.experimentclass.id = :classIds ",["classIds":classIds])
          }
      }

      if(organsList!=null && organsList.size()>0){
        organsList = CommonUtil.getInstance().getDistinctList(organsList)
      }

      gLogger.info "Organs Count :: ${organsList?.size()}"

      return organsList
    }

    /**
     * to get the distinct list of organs
     * @return
     */
    Collection<OrganVO> getUniqueSxOrgans() {
        Collection<OrganVO> organVOList = null
        def uniqueList = ClassOrgan.executeQuery("Select distinct co.organ_name from setupx.entity.ClassOrgan co where co.organ_name != ''")

        OrganVO organVO = null
        if(uniqueList!=null && uniqueList.size()>0){
           // prepare unique list of organs
           uniqueList = CommonUtil.getInstance().getDistinctList(uniqueList)

           organVOList = new ArrayList<OrganVO>()
           uniqueList.each {organName->
               gLogger.info "************Process Organ ::: ${organName}*******************"
               organVO = getOrganDataByOrganName(organName)
               //gLogger.info "ExperiemntCount :: ${organVO.getExperimentCount()}"
               organVOList.add(organVO)
           }
        }
        return organVOList
    }

    /**
     * get organ data by organ name
     * @param organName
     * @return
     */
    OrganVO getOrganDataByOrganName(String organName){
       //gLogger.info "organName:: ${organName}"
       OrganVO organVO = OrganUtil.getInstance().getOrganDataByOrganName(organName)
       return organVO
    }

    /**
     * get organ data by organ name with wild card
     * @param organName
     * @param params
     * @param wildCards
     * @return
     */
    Collection<OrganVO> getOrganDataByOrganNameWithWildCards(String organName, Map params = [:],def wildCards = true){
       gLogger.info "organName:: ${organName}"
       def organVOList = []
       if ( organName instanceof String && wildCards) {
          organName = WildCardUtil.getInstance().convertToLikeWildCard(organName)
       }
       gLogger.info "organName:: ${organName}"

       def organsList = ClassOrgan.executeQuery("Select distinct co.organ_name from setupx.entity.ClassOrgan co where co.organ_name != '' and upper(co.organ_name) like :organName ",["organName":organName.toUpperCase()],params)
       // or upper(e.tissue) like :search or upper(e.cell_type) like :search or upper(e.subcellular_celltype) like :search
       if(organsList!=null && organsList.size()>0){
         OrganVO organVO = null
         organVOList = new ArrayList<OrganVO>()
         organsList = CommonUtil.getInstance().getDistinctList(organsList)
         if(organsList!=null){
            if(organsList instanceof Collection && organsList.size()>0){
                organsList.each{organ->
                   organVO = getOrganDataByOrganName(organ)
                   gLogger.info "ExperiemntCount :: ${organVO.getExperimentCount()}"
                   organVOList.add(organVO)
               }
            }else if(organsList instanceof String[] && organsList.length > 0){
                organsList.each{organ->
                   organVO = getOrganDataByOrganName(organ)
                   gLogger.info "ExperiemntCount :: ${organVO.getExperimentCount()}"
                   organVOList.add(organVO)
               }
            }else{
               String organ = organsList.toString()
               organVO = getOrganDataByOrganName(organ)
               gLogger.info "ExperiemntCount :: ${organVO.getExperimentCount()}"
               organVOList.add(organVO)
            }
         }
       }
       return organVOList
    }

    /**
     * get the list of class Ids for the organ name
     * @param organName
     * @return
     */
    def getClassIdsByOrganName(String organName){
        def idList

        if(organName!=null){
            idList = ClassOrgan.executeQuery("Select distinct co.experimentclass.id from setupx.entity.ClassOrgan co where upper(co.organ_name) = :organName ",["organName":organName.toUpperCase()])
            gLogger.info "ClassIds Count :: ${idList?.size()}"
        }

        return idList
    }

    /**
     * to get the list of sample Ids for the organ name
     * @param organName
     * @return
     */
    def getSampleIdsByOrganName(String organName){
        def classIds = getClassIdsByOrganName(organName)
        def idList
        if(classIds!=null){
            if( classIds instanceof Collection){
                if(classIds?.size()!=0){
                    idList = ClassSample.executeQuery("Select distinct cs.id from setupx.entity.ClassSample cs where cs.experimentclass.id in (:classIds) and cs.label != null and cs.label!='' ",["classIds":classIds])
                }
            }else if( classIds instanceof Long){
                idList = ClassSample.executeQuery("Select distinct cs.id from setupx.entity.ClassSample cs where cs.experimentclass.id = :classIds and cs.label != null and cs.label!='' ",["classIds":classIds])
            }

        }
        gLogger.info "SampleIds Count :: ${idList?.size()}"

        return idList
    }

}
